﻿# coding: utf-8
import wx

import mk3de
import RefCounter
import Engine
import Camera
import RenderDevice
import ToolTranslation
import ToolRotation
import ToolScale
import SceneNode
import SceneManager
import Painter
import Profiler
import Model
import Skeleton
import RenderWindow
import RenderFrame
import RenderStepViewCulling
import RenderStepSceneRender
import CullingProcessorDefault
import EntityModel
import Transformation

class CModelEditor:
    def __init__(self):
        self._modelEntityHandle = 0
        self._sceneHandle = 0
        self._cameraHandle = 0
        
    def Create(self):
        ## Initialize engine.
        hWnd = wx.GetApp()._mainFrame._panelList[ID_PANEL_MODEL].GetHandle()
        if not mk3de.CreateEngine(Engine.RDT_DIRECT3D9, hWnd):
            return False
            
        ## Create camera.
        self._cameraHandle = Camera._New()
        self.ResetCamera()
        Engine.SetCurrentCamera(self._cameraHandle)
        
        ## Create transfom tools
        self.__CreateTransformTools()
        
        ## Create scene.
        self.__CreateScene()
        
        ## Create render window.
        self.__CreateRenderWindow(hWnd)
        
        return True
        
    def __CreateScene(self):
        self._sceneHandle = SceneManager.CreateScene('ModelEditorScene')
        
    def __CreateRenderWindow(self, hWnd):
        renderWindow = Engine.CreateRenderWindow(hWnd)
        RenderFrame.MakeDefaultRenderSteps(renderWindow)
        
        renderStepViewCulling = RenderFrame.GetRenderStepByName(renderWindow, RenderStepViewCulling.RenderStepName)
        RenderStepViewCulling.SetCamera(renderStepViewCulling, self._cameraHandle)
        cullingProcessorDefault = CullingProcessorDefault._New()
        RenderStepViewCulling.SetCullingProcessor(renderStepViewCulling, cullingProcessorDefault)
        RefCounter.Release(cullingProcessorDefault)
        RenderStepViewCulling.SetScene(renderStepViewCulling, self._sceneHandle)
        
        renderStepSceneRender = RenderFrame.GetRenderStepByName(renderWindow, RenderStepSceneRender.RenderStepName)        
        RenderStepSceneRender.SetClearParam(renderStepSceneRender, True, True, True, 0xff808080, 1.0, 0)
        
    def ResetCamera(self):
        if not self._cameraHandle:
            return
            
        Camera.SetPosition(self._cameraHandle, 0, 400, -300)
        Camera.SetLookDirection(self._cameraHandle, 0, -1, 1)
        Camera.SetUpDirection(self._cameraHandle, 0, 1, 0)
        
    def __CreateTransformTools(self):
        self._toolTrans = ToolTranslation._New()
        self._toolRot = ToolRotation._New()
        self._toolScale = ToolScale._New()
        
        ToolTranslation.Enable(self._toolTrans, 0)
        ToolRotation.Enable(self._toolRot, 0)
        ToolScale.Enable(self._toolScale, 0)
        
        return True
    
    def __DestroyTransformTools(self):
        ToolTranslation._Delete(self._toolTrans)
        ToolRotation._Delete(self._toolRot)
        ToolScale._Delete(self._toolScale)    
                
    def Destroy(self):
        self.__DestroyTransformTools()
        RefCounter.Release(self._cameraHandle)
        RefCounter.Release(self._sceneHandle)
        mk3de.DestroyEngine()

    def Update(self):
        """
        x, y, z = Transformation.GetRelativeTranslation(SceneNode._CTransformation(self._sceneHandle))
        x += 0.5
        if x > 500:
            x = 0
            
        Transformation.SetRelativeTranslation(SceneNode._CTransformation(self._sceneHandle), x, y, z)
        """
        
        Engine.Update()

    def Render(self):
        self.__RenderMainWindow()
        
    def __RenderMainWindow(self):
        hWnd = wx.GetApp()._mainFrame._panelList[ID_PANEL_MODEL].GetHandle()
        renderWindow = Engine.GetRenderWindow(hWnd)
        Engine.SetCurrentRenderWindow(renderWindow)
        
        width = RenderWindow.GetWidth(renderWindow)
        height = RenderWindow.GetHeight(renderWindow)
        RenderDevice.SetViewport(0, 0, width, height, 0, 1.0)
        
        RenderDevice.BeginFrame()
        Profiler.BeginFrame()
        
        RenderFrame.Render(renderWindow)
        self.__RenderGrid()
        self.__RenderTransformTools()
        
        Profiler.ShowStatistics()
        Profiler.EndFrame()
        
        Painter.Flush()
        
        RenderDevice.EndFrame()
        RenderDevice.Present(renderWindow)
        
    def __RenderTransformTools(self):
        RenderDevice.Clear(0, 1, 1, 0xff000000, 1.0, 0)
        ToolTranslation.Render(self._toolTrans)
        ToolRotation.Render(self._toolRot)
        ToolScale.Render(self._toolScale)

    def __RenderGrid(self):
        for i in xrange(-500, 501, 50):
            Painter.DrawLine3D(-500, 0, i, 500, 0, i, 0xffa0a0a0, 0xffa0a0a0)
        for i in xrange(-500, 501, 50):
            Painter.DrawLine3D(i, 0, -500, i, 0, 500, 0xffa0a0a0, 0xffa0a0a0)
            
        Painter.DrawLine3D(-500, 0, 0, 500, 0, 0, 0xff404040, 0xff404040);
        Painter.DrawLine3D(0, 0, -500, 0, 0, 500, 0xff404040, 0xff404040);
        Painter.Flush()
        
    def OpenModel(self, path):
        if path.startswith(GLOBAL_SETTING._general._workDir):
            path = path[len(GLOBAL_SETTING._general._workDir):]
        
        if self._modelEntityHandle:
            EntityModel._Delete(self._modelEntityHandle)
            
        self._modelEntityHandle = EntityModel._New(self._sceneHandle)
        if not EntityModel.LoadFromFile(self._modelEntityHandle, path):        
            EntityModel._Delete(self._modelEntityHandle)
            self._modelHandle = 0
            return False

        SceneNode.AttachEntity(self._sceneHandle, self._modelEntityHandle)
        return True
            
    def NewModel(self):
        if self._modelEntityHandle:
            EntityModel._Delete(self._modelEntityHandle)
            
        self._modelEntityHandle = EntityModel._New(self._sceneHandle)
        if not self._modelEntityHandle:
            dlg = wx.MessageDialog(self, TD.ERROR_NEW_MODEL_FAILED, TD.ERROR_TITLE, wx.OK|wx.ICON_INFORMATION)
            dlg.ShowModal()
            dlg.Destroy()              
            self._modelEntityHandle = 0
            return  
                        
__builtins__['MODEL_EDITOR'] = CModelEditor()
